/**
 * 公共配置
 */

import Vue from 'vue'
// 加载 Vant 核心组件库
import { Toast } from 'vant'
// 注册使用 Vant 组件库
Vue.use(Toast)

// 使用常量保存本地存储的存储名称 以防字符串输入错误导致程序运行异常
// 本地存储的token身份认证
export const TOKEN_KEY = 'HOUSEKEEPING_PLATFORM_USER_TOKEN'

/**
 * trycatch 异常处理函数
 */
// && 逻辑中断运算, 前面的表达式必须为真才会执行后面的表达式, 为假则中断后面代码执行
// || 逻辑中断运算, 前面的表达式必须为假才会执行后面的表达式, 为真则中断后面代码执行
// bug 版本1: 发现 toast 不能只传一个, 要传的话成功失败的都要传, 不知道是个什么情况, 解决不了了, 裂开(但是这个bug并不影响, 传两个就好了)
// 箭头函数没有 arguments 所以这里用 function
export async function trycatch () {
  // 这里利用 arguments 实现形参可以随意传送, 实现可传可不传, 而且形参传入顺序可以随意传入
  const flag = { fn: true, obj: true, arr: true, str: true, num: true, bool: true }
  const obj = { ...arguments }

  for (const key in obj) {
    const item = obj[key]
    if (typeof item === 'object') obj.options = item
    if (typeof item === 'string' && !flag.str) obj.errMsg = item
    if (typeof item === 'string' && flag.str) {
      obj.msg = item
      flag.str = false
    }
    if (typeof item === 'number') obj.status = item
    if (typeof item === 'boolean') obj.flag = item
    if (typeof item === 'function' && !flag.fn) obj.error = item
    // 经过多次测试发现 Promise转换为JSON格式字符串后为 '{}'
    // 所以在此判断 JSON.stringify(item) === '{}' 如果是Promise数据 则 obj.success 将会是一个对象
    // 就可以判断 typeof obj.success 是否是 'function' 或者 JSON.stringify(obj.success) 是否是 '{}'
    if ((typeof item === 'function' && flag.fn) || JSON.stringify(item) === '{}') {
      obj.success = item
      flag.fn = false
    }
  }

  // 这里是真正实现 trycatch 异常处理函数的核心代码
  // 判断有没有传入 msg 属性, 没有传入则给个默认值
  if (!obj.msg) obj.msg = '操作'
  try {
    // 以下代码实现了 可以给 obj.success 传两种形式 一个是回调函数的形式 一个是函数调用的形式
    // 回调函数可以添加自己的逻辑 不只是发送请求
    // 函数调用的形式就是只用发送请求不需要返回值的那种就可以采用这种 比如删除请求
    // 最新版
    // console.log('arguments[0]: ', await arguments[0])
    // console.log('arguments[0]: ', JSON.stringify(arguments[0]))
    // console.log('arguments[0]: ', JSON.stringify(arguments[0]) === '{}')
    const res = typeof obj.success === 'function' ? await obj.success() : await obj.success

    // 第一版
    // if (typeof obj.success !== 'function') return await obj.success
    // obj.success = obj.success && typeof obj.success === 'function' && obj.success()
    // typeof obj.success === 'function' ? obj.success() : await obj.success

    // 第二版
    // obj.success = typeof obj.success === 'function' ? obj.success() : obj.success
    // if (typeof obj.success !== 'function') { res = await obj.success }

    // 成功轻提示
    // 判断有没有传入 flag 属性, 没有传入则给个默认值为 false
    if (!obj.flag) obj.flag = false
    // 若传入的 toast 属性是数组, 则调用数组第一个, 为成功的方法
    let toast = obj.options && obj.options.toast
    if (toast && obj.flag) toast = Array.isArray(toast) ? toast[0] : toast
    // 若传入了 toast 属性, 则调用传入的方法, 否则调用 Toast() 弹出轻提示
    // 若传入了 toast 属性和 flag 属性为 true, 则调用传入的方法, 否则不执行
    toast && obj.flag && toast(`${obj.msg}成功`)
    // 只有 flag 属性为 true 的情况下才调用 Toast() 弹出轻提示
    if (!toast && obj.flag) Toast(`${obj.msg}成功`)

    // console.log('res: ', res)
    return res
  } catch (error) {
    console.log(`${obj.msg}失败`, error)
    // 失败轻提示
    // 若传入的 toast 属性是数组, 则调用数组第二个, 为失败的方法
    let toast = obj.options && obj.options.toast
    if (toast) toast = Array.isArray(toast) ? toast[1] : toast
    // 判断是否传入 obj.status
    if (error.response && error.response.status === obj.status) {
      // 若传入了 toast 属性, 则调用传入的方法, 否则调用 Toast() 弹出轻提示
      toast && toast(obj.errMsg)
      toast || Toast(obj.errMsg)

      // 判断是否传入 obj.error 函数
      if (obj.error && typeof obj.error === 'function') return obj.error(error)
    } else {
      // 判断是否传入 obj.error 函数
      if (obj.error && typeof obj.error === 'function') return obj.error(error)

      // 若传入了 toast 属性, 则调用传入的方法, 否则调用 Toast() 弹出轻提示
      toast && toast(`${obj.msg}失败, 请稍后重试`)
      toast || Toast(`${obj.msg}失败, 请稍后重试`)
    }
  }
}

/**
 * 处理两端空字符串
 */
export const validEmptyString = data => {
  if (Array.isArray(data)) {
    data.forEach(item => {
      Object.keys(item).forEach(key => {
        if (typeof item[key] === 'string') {
          item[key] = item[key].trim()
        }
      })
    })
  } else if (typeof data === 'object') {
    Object.keys(data).forEach(item => {
      if (typeof data[item] === 'string') {
        data[item] = data[item].trim()
      }
    })
  }
}
